<?php
namespace App\Common\Oss;

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use OSS\Core\OssException;
use OSS\OssClient;

class OssObject
{

    protected $accessKeyId;
    protected $accessKeySecret;
    protected $endpoint;
    protected $bucket;
    protected $region;
    protected $schema;
    protected static $ossClient;

    public function __construct($bucket = '', $region = "oss-cn-beijing", $schema = "https")
    {
        $config = Config::get('BaseConfig.oss');

        $this->accessKeyId = $config['accessKeyId'];
        $this->accessKeySecret = $config['accessKeySecret'];
        $this->endpoint = $config['endpoint'];
        $this->region = $config['region'];
        $this->schema = $config['schema'];
        $this->bucket = $bucket;

    }

    public function setBucket($bucket)
    {
        $this->bucket = $bucket;
    }

    /**
     * 初始话
     */
    private function init()
    {
        self::$ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint, false);
    }

    /**
     * 上传文件
     * @param $body  //本地文件路径
     * @param $key   //oss 上传路径
     * @param array $options
     * @return string
     */
    public function putObject($body, $key, $options = [])
    {
        $this->init();
        try {
            $result = $this::$ossClient->uploadFile(
                $this->bucket,
                $key,
                $body,
                $options
            );
            // 请求成功
            return $result;
        } catch (\Exception $e) {
            // 请求失败
            return $e->getMessage();
        }
    }

    /**
     * 返回上传结果
     * @param $bucket
     * @param string $region
     * @param $body
     * @param $key
     * @return string
     */
    public function uploadOss($bucket, $region = 'ap-beijing', $body, $key)
    {
        $options = [];
        $res = $this->putObject($body, $key, $options);
        return $res;
    }


    /**
     * 下载到本地文件
     * @param $key
     * @param $localfile
     * @return bool
     */
    public function getObjectInfo($key, $localfile)
    {
        $options = [
            OssClient::OSS_FILE_DOWNLOAD => $localfile
        ];
        $this->init();
        try {
            $this::$ossClient->getObject($this->bucket, $key, $options);
        } catch (OssException $e) {
            return false;
        }
        return true;
    }

    /**
     * 获取某个目录下文件数据临时地址
     * @param $prefix
     * @param int $max
     * @param int $overdueTime
     * @return array
     */
    public function listObjects($prefix, $max = 100, $overdueTime = 60)
    {
        $this->init();

        $url_arr = [];
        $result = [];
        while (true) {
            try {
                $options = array(
                    'delimiter' => '/',
                    'prefix' => $prefix,
                    'max-keys' => $max,
                    //'marker' => '',
                );
                $listObjectInfo = $this::$ossClient->listObjects($this->bucket, $options);
            } catch (OssException $e) {
                return [];
            }
            // 得到nextMarker，从上一次listObjects读到的最后一个文件的下一个文件开始继续获取文件列表。
            $nextMarker = $listObjectInfo->getNextMarker();
            $listObject = $listObjectInfo->getObjectList();
            $listPrefix = $listObjectInfo->getPrefixList();
            if (!empty($listObject)) {
                foreach ($listObject as $objectInfo) {
                    $result[] = $objectInfo->getKey();
                }
            }
//            if (!empty($listPrefix)) {
//                print("prefixList: \n");
//                foreach ($listPrefix as $prefixInfo) {
//                    $result2[] = $prefixInfo->getPrefix();
//                }
//            }
            if ($listObjectInfo->getIsTruncated() !== "true") {
                break;
            }
        }
        if (empty($result)) {
            return [];
        }
        $data = array_splice($result, 1);
        $time = time();
        foreach ($data as $key => $value) {
            $signedUrl = $this::$ossClient->generatePresignedUrl($this->bucket, $value, $time + $overdueTime); //签名的有效时间
            array_push($url_arr, $signedUrl);
        }
        return $url_arr;
    }

    /**
     * 删除oss中指定文件
     * @param $key
     * @return string
     */
    public function delObject($key)
    {
        $this->init();
        try {
            $result = $this::$ossClient->deleteObject($this->bucket, $key);
            // 请求成功
            return $result;
        } catch (\Exception $e) {
            // 请求失败
            return $e->getMessage();
        }
    }

    /**
     * 删除oss中多个文件
     * @param $keys //数组多个文件地址
     * @return string
     */
    public function delObjects($keys)
    {
        $this->init();
        try {
            $result = $this::$ossClient->deleteObjects($this->bucket, $keys);
            // 请求成功
            return $result;
        } catch (\Exception $e) {
            // 请求失败
            return $e->getMessage();
        }
    }

    /**
     * 获取临时地址
     * @param $key
     * @param int $time
     * @return string
     */
    public function getObjectUrl($key, $time = 60)
    {
        $this->init();
        try {
            $expiration = time() + $time;
            $signedUrl = $this::$ossClient->generatePresignedUrl($this->bucket, $key, $expiration); //签名的有效时间
            return $signedUrl;
        } catch (\Exception $e) {
            // 请求失败
            Log::info($e->getMessage());
            return '';
        }
    }

}
